﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "ControlDefinitionFactory.h"
#include "ControlDefinitionLibrary.h"
#include "LabelDefinition.h"
#include "LabelDefinitionReference.h"
#include "GalleryDefinition.h"
#include "GalleryDefinitionReference.h"
#include "CommandButtonMenuDefinition.h"
#include "CommandButtonMenuDefinitionReference.h"
#include "CommandMenuItemDefinition.h"
#include "CommandMenuItemDefinitionReference.h"
#include "LineEditDefinition.h"
#include "RadioButtonGroupDefinition.h"
#include "RadioButtonGroupDefinitionReference.h"
#include "CheckBoxGroupDefinition.h"
#include "CheckBoxGroupDefinitionReference.h"
#include "ComboBoxDefinition.h"
#include "ComboBoxDefinitionReference.h"
#include "CommandButtonDefinition.h"
#include "ProgressBarDefinition.h"
#include "GbmpNew.h"
#include "LineEditDefinitionReference.h"
#include "ProgressBarDefinitionReference.h"
#include "CommandButtonDefinitionReference.h"
#include "MenuItemContainerDefinition.h"
#include "MenuItemContainerDefinitionReference.h"
#include "UiManager.h"
#include "ControlDefinitionUtil.h"
#include "MenuItemDefinition.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

namespace
{

    ControlDefinitionFactory s_factory;

}

ControlDefinitionFactory::ControlDefinitionFactory()
{
    m_pFactory = this;
}

ControlDefinitionFactory::~ControlDefinitionFactory()
{
    m_pFactory = nullptr;
}

OwnerPtr<IGalleryDefinition> ControlDefinitionFactory::CreateGallery(const std::wstring& id, const std::wstring& caption, int columnCount, int itemWidth, int itemHeight)
{
    return NEW_AS_OWNER_PTR(GalleryDefinition, id, caption, columnCount, itemWidth, itemHeight);
}

OwnerPtr<IGalleryDefinition> ControlDefinitionFactory::CreateGalleryReference(const IGalleryDefinition* pGalleryDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pGalleryDefinition, L"传入的pGalleryDefinition为空",L"GDMPLab",L"2024-03-30");
    const GalleryDefinition* pDefinition = dynamic_cast<const GalleryDefinition*>(pGalleryDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    IGalleryDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<IGalleryDefinition>(pGalleryDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pGalleryDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(GalleryDefinitionReference, const_cast<GalleryDefinition*>(pDefinition));
}

OwnerPtr<ICommandButtonMenuDefinition> ControlDefinitionFactory::CreateCommandButtonMenu(const std::wstring& id, const std::wstring& commandId, const std::wstring& caption, const std::wstring& iconPath, const std::wstring& tooltip)
{
    return NEW_AS_OWNER_PTR(CommandButtonMenuDefinition, id, commandId, caption, iconPath, tooltip);
}

OwnerPtr<ICommandButtonMenuDefinition> ControlDefinitionFactory::CreateCommandButtonMenuReference(const ICommandButtonMenuDefinition* pCommandButtonMenuDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pCommandButtonMenuDefinition, L"传入的pCommandButtonMenuDefinition为空",L"GDMPLab",L"2024-03-30");
    const CommandButtonMenuDefinition* pDefinition = dynamic_cast<const CommandButtonMenuDefinition*>(pCommandButtonMenuDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    ICommandButtonMenuDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<ICommandButtonMenuDefinition>(pCommandButtonMenuDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pCommandButtonMenuDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(CommandButtonMenuDefinitionReference, const_cast<CommandButtonMenuDefinition*>(pDefinition));
}

OwnerPtr<ICommandMenuItemDefinition> ControlDefinitionFactory::CreateCommandMenuItem(const std::wstring& id, const std::wstring& commandId, const std::wstring& caption, const std::wstring& tooltip, const std::wstring& iconPath)
{
    return NEW_AS_OWNER_PTR(CommandMenuItemDefinition, id, commandId, caption, tooltip, iconPath);
}

gcmp::OwnerPtr<gcmp::ICommandMenuItemDefinition> gcmp::ControlDefinitionFactory::CreateCommandMenuItemReference(const ICommandMenuItemDefinition* pCommandMenuItemDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pCommandMenuItemDefinition, L"传入的pCommandMenuItemDefinition为空",L"GDMPLab",L"2024-03-30");
    const CommandMenuItemDefinition* pDefinition = dynamic_cast<const CommandMenuItemDefinition*>(pCommandMenuItemDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    ICommandMenuItemDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<CommandMenuItemDefinition>(pCommandMenuItemDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pCommandMenuItemDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(CommandMenuItemDefinitionReference, const_cast<CommandMenuItemDefinition*>(pDefinition));
}

OwnerPtr<ILineEditDefinition> ControlDefinitionFactory::CreateLineEdit(const std::wstring& id, const std::wstring& caption, LineEditInputType inputType)
{
    return NEW_AS_OWNER_PTR(LineEditDefinition, id, caption, inputType);
}

OwnerPtr<IRadioButtonGroupDefinition> ControlDefinitionFactory::CreateRadioButtonGroup(const std::wstring& id, const std::wstring& caption)
{
    return NEW_AS_OWNER_PTR(RadioButtonGroupDefinition, id, caption);
}

OwnerPtr<ICheckBoxGroupDefinition> ControlDefinitionFactory::CreateCheckBoxGroup(const std::wstring& id, const std::wstring& caption)
{
    return NEW_AS_OWNER_PTR(CheckBoxGroupDefinition, id, caption);
}

OwnerPtr<IComboBoxDefinition> ControlDefinitionFactory::CreateComboBox(const std::wstring& id, const std::wstring& caption)
{ 
    return NEW_AS_OWNER_PTR(ComboBoxDefinition, id, caption);
}

OwnerPtr<ICommandButtonDefinition> ControlDefinitionFactory::CreateCommandButton(const std::wstring& id, const std::wstring& caption, const std::wstring& tooltip, const std::wstring& commandId, const std::wstring& iconPath, ButtonStyle buttonStyle)
{
    return NEW_AS_OWNER_PTR(CommandButtonDefinition, id, caption, tooltip, commandId,iconPath,buttonStyle);
}

OwnerPtr<ICommandButtonDefinition> ControlDefinitionFactory::CreateCommandButtonReference(const ICommandButtonDefinition* pCommandButtonDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pCommandButtonDefinition, L"传入的pCommandButtonDefinition为空",L"GDMPLab",L"2024-03-30");
    const CommandButtonDefinition* pDefinition = dynamic_cast<const CommandButtonDefinition*>(pCommandButtonDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    ICommandButtonDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<ICommandButtonDefinition>(pCommandButtonDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pCommandButtonDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(CommandButtonDefinitionReference, const_cast<CommandButtonDefinition*>(pDefinition));
}

OwnerPtr<ILabelDefinition> ControlDefinitionFactory::CreateLabel(const std::wstring& id, const std::wstring& caption, const std::wstring& tooltip)
{
    return NEW_AS_OWNER_PTR(LabelDefinition, id, caption, tooltip);
}

OwnerPtr<ILabelDefinition> ControlDefinitionFactory::CreateLabelReference(const ILabelDefinition* pLabelDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLabelDefinition, L"传入的pLabelDefinition为空",L"GDMPLab",L"2024-03-30");
    const LabelDefinition* pDefinition = dynamic_cast<const LabelDefinition*>(pLabelDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    ILabelDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<ILabelDefinition>(pLabelDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pLabelDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(LabelDefinitionReference, const_cast<LabelDefinition*>(pDefinition));
}

OwnerPtr<IProgressBarDefinition> ControlDefinitionFactory::CreateProgressBar(const std::wstring& id, const std::wstring& caption, const std::wstring& tooltip, int length)
{
    return NEW_AS_OWNER_PTR(ProgressBarDefinition, id, caption, tooltip, length);
}

gcmp::OwnerPtr<gcmp::IProgressBarDefinition> gcmp::ControlDefinitionFactory::CreateProgressBarReference(const IProgressBarDefinition* pProgressBarDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pProgressBarDefinition, L"传入的pProgressBarDefinition为空",L"GDMPLab",L"2024-03-30");
    const ProgressBarDefinition* pDefinition = dynamic_cast<const ProgressBarDefinition*>(pProgressBarDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    IProgressBarDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<IProgressBarDefinition>(pProgressBarDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition==pProgressBarDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(ProgressBarDefinitionReference, const_cast<ProgressBarDefinition*>(pDefinition));
}


ControlDefinitionLibrary* ControlDefinitionFactory::GetControlDefinitionLibrary() const
{
    return dynamic_cast<ControlDefinitionLibrary*>(IControlDefinitionLibrary::Get());
}

gcmp::OwnerPtr<gcmp::ILineEditDefinition> gcmp::ControlDefinitionFactory::CreateLineEdit(const std::wstring& id, const std::wstring& caption, double value, int decimals)
{
    return NEW_AS_OWNER_PTR(LineEditDefinition, id, caption, value,decimals);
}

gcmp::OwnerPtr<gcmp::ILineEditDefinition> gcmp::ControlDefinitionFactory::CreateLineEditReference(const ILineEditDefinition* pLineEditDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLineEditDefinition, L"pLineEditDefinition为空",L"GDMPLab",L"2024-03-30");
    const LineEditDefinition* pDefinition = dynamic_cast<const LineEditDefinition*>(pLineEditDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    ILineEditDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<ILineEditDefinition>(pDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pLineEditDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(LineEditDefinitionReference, const_cast<LineEditDefinition*>( pDefinition));
}

gcmp::OwnerPtr<gcmp::IRadioButtonGroupDefinition> gcmp::ControlDefinitionFactory::CreateRadioButtonGroupReference(const IRadioButtonGroupDefinition* pRadioButtonGroupDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pRadioButtonGroupDefinition, L"pRadioButtonGroupDefinition为空",L"GDMPLab",L"2024-03-30");
    const RadioButtonGroupDefinition* pDefinition = dynamic_cast<const RadioButtonGroupDefinition*>(pRadioButtonGroupDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    IRadioButtonGroupDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<IRadioButtonGroupDefinition>(pDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pRadioButtonGroupDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(RadioButtonGroupDefinitionReference, const_cast<RadioButtonGroupDefinition*>(pDefinition));
}

gcmp::OwnerPtr<gcmp::ICheckBoxGroupDefinition> gcmp::ControlDefinitionFactory::CreateCheckBoxGroupReference(const ICheckBoxGroupDefinition* pCheckBoxGroupDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pCheckBoxGroupDefinition, L"pCheckBoxGroupDefinition为空",L"GDMPLab",L"2024-03-30");
    const CheckBoxGroupDefinition* pDefinition = dynamic_cast<const CheckBoxGroupDefinition*>(pCheckBoxGroupDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    ICheckBoxGroupDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<ICheckBoxGroupDefinition>(pDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pCheckBoxGroupDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(CheckBoxGroupDefinitionReference, const_cast<CheckBoxGroupDefinition*>(pDefinition));
}

gcmp::OwnerPtr<gcmp::IComboBoxDefinition> gcmp::ControlDefinitionFactory::CreateComboBoxReference(const IComboBoxDefinition* pComboBoxDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pComboBoxDefinition, L"pComboBoxDefinition为空",L"GDMPLab",L"2024-03-30");
    const ComboBoxDefinition* pDefinition = dynamic_cast<const ComboBoxDefinition*>(pComboBoxDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    IComboBoxDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<IComboBoxDefinition>(pDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pComboBoxDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(ComboBoxDefinitionReference, const_cast<ComboBoxDefinition*>(pDefinition));
}

gcmp::OwnerPtr<IMenuItemContainerDefinition> gcmp::ControlDefinitionFactory::CreateMenuItemContainer(const std::wstring& id, const std::wstring& caption)
{
    return NEW_AS_OWNER_PTR(MenuItemContainerDefinition, id, caption);
}

gcmp::OwnerPtr<IMenuItemDefinition> gcmp::ControlDefinitionFactory::CreateSeparator()
{
    return NEW_AS_OWNER_PTR(SeparatorItemDefinition);
}

gcmp::OwnerPtr<gcmp::IMenuItemContainerDefinition> gcmp::ControlDefinitionFactory::CreateMenuItemContainerReference(const IMenuItemContainerDefinition* pMenuItemContainerDefinition)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pMenuItemContainerDefinition, L"pComboBoxDefinition为空",L"GDMPLab",L"2024-03-30");
    const MenuItemContainerDefinition* pDefinition = dynamic_cast<const MenuItemContainerDefinition*>(pMenuItemContainerDefinition);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDefinition, L"不能通过引用创建引用",L"GDMPLab",L"2024-03-30");
    IMenuItemContainerDefinition* pLibraryControlDefinition = ControlDefinitionLibraryUtil::GetControlDefinition<IMenuItemContainerDefinition>(pDefinition->GetId());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLibraryControlDefinition == pMenuItemContainerDefinition, L"创建引用的对象需先加到library",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(MenuItemContainerDefinitionReference, const_cast<MenuItemContainerDefinition*>(pDefinition));
}

gcmp::IUiManager* gcmp::ControlDefinitionFactory::GetUiManager()
{
    return UiManager::GetInstance();
}

bool gcmp::ControlDefinitionFactory::IsReference(const IControlDefinition* pControlDefinition)
{
    return ControlDefinitionUtil::IsReference(pControlDefinition);
}

